package com.shanzhu.beadhouse.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shanzhu.beadhouse.common.constant.ExceptionEnum;
import com.shanzhu.beadhouse.common.constant.YesNoEnum;
import com.shanzhu.beadhouse.common.util.AssertUtil;
import com.shanzhu.beadhouse.common.util.PageUtil;
import com.shanzhu.beadhouse.entity.base.PageResult;
import com.shanzhu.beadhouse.entity.base.Result;
import com.shanzhu.beadhouse.dao.mapper.CateringSetMapper;
import com.shanzhu.beadhouse.dao.mapper.SetDishesMapper;
import com.shanzhu.beadhouse.dao.mapper.DishesMapper;
import com.shanzhu.beadhouse.entity.po.CateringSet;
import com.shanzhu.beadhouse.entity.po.Dishes;
import com.shanzhu.beadhouse.entity.po.SetDishes;
import com.shanzhu.beadhouse.entity.query.OperateCateringSetQuery;
import com.shanzhu.beadhouse.entity.query.PageCateringSetByKeyQuery;
import com.shanzhu.beadhouse.entity.vo.CateringSetDetailVO;
import com.shanzhu.beadhouse.entity.vo.DishesVO;
import com.shanzhu.beadhouse.entity.vo.PageCateringSetByKeyVo;
import com.shanzhu.beadhouse.service.CateringSetService;
import com.shanzhu.beadhouse.service.DishesService;
import com.shanzhu.beadhouse.service.common.CateringSetFunc;
import com.shanzhu.beadhouse.service.common.DishesFunc;
import com.shanzhu.beadhouse.service.common.ElderFunc;
import com.shanzhu.beadhouse.service.common.SetDishesFunc;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class CateringSetServiceImpl implements CateringSetService {

    @Resource
    private CateringSetMapper cateringSetMapper;
    @Resource
    private CateringSetFunc cateringSetFunc;
    @Resource
    private SetDishesMapper setDishesMapper;
    @Resource
    private SetDishesFunc setDishesFunc;
    @Resource
    private ElderFunc elderFunc;
    @Resource
    private PageUtil pageUtil;
    @Resource
    private DishesMapper dishesMapper;
    @Resource
    private DishesService dishesService; // 添加缺失的注入

    @Override
    public Result pageCateringSetByKey(PageCateringSetByKeyQuery query) {
        List<CateringSet> listNotDelCateringSet = cateringSetFunc.listNotDelCateringSet(query.getSetName());
        List<PageCateringSetByKeyVo> pageCateringSetByKeyVoList = BeanUtil.copyToList(listNotDelCateringSet, PageCateringSetByKeyVo.class);
        PageResult<PageCateringSetByKeyVo> pageResult = pageUtil.packPageResultData(pageCateringSetByKeyVoList, query.getPageNum(), query.getPageSize());
        return Result.success(pageResult);
    }

    @Transactional
    public Result addCateringSet(OperateCateringSetQuery query) {
        AssertUtil.isNull(cateringSetFunc.getCateringSetByName(query.getName()), ExceptionEnum.SET_REPEAT);

        query.setId(null);
        CateringSet cateringSet = BeanUtil.toBean(query, CateringSet.class);
        cateringSet.setDelFlag(YesNoEnum.NO.getCode());
        cateringSetMapper.insert(cateringSet);
        setDishesFunc.saveBatchSetDishes(query, cateringSet.getId());
        return Result.success();
    }

    @Transactional
    public Result editCateringSet(OperateCateringSetQuery query) {
        CateringSet cateringSetByName = cateringSetFunc.getCateringSetByName(query.getName());
        boolean checkName = cateringSetByName != null && !Objects.equals(cateringSetByName.getId(), query.getId());
        AssertUtil.notTrue(checkName, ExceptionEnum.SET_REPEAT);

        CateringSet cateringSet = BeanUtil.toBean(query, CateringSet.class);
        cateringSetMapper.updateById(cateringSet);
        setDishesFunc.saveBatchSetDishes(query, cateringSet.getId());
        return Result.success();
    }

    @Override
    public Result getCateringSetById(Long setId) {
        // 1. 查询套餐基本信息
        CateringSet cateringSet = cateringSetMapper.selectById(setId);
        AssertUtil.notNull(cateringSet, ExceptionEnum.DATA_NOT_EXIST);

        // 2. 查询套餐菜品关系
        List<SetDishes> setDishesList = setDishesMapper.selectList(
                new LambdaQueryWrapper<SetDishes>()
                        .eq(SetDishes::getSetId, setId)
        );

        // 3. 转换为每日每餐结构
        Map<Integer, Map<Integer, List<DishesVO>>> mealPlans = new HashMap<>();

        // 初始化7天3餐的结构
        for (int day = 1; day <= 7; day++) {
            Map<Integer, List<DishesVO>> dayMeals = new HashMap<>();
            for (int meal = 1; meal <= 3; meal++) {
                dayMeals.put(meal, new ArrayList<>());
            }
            mealPlans.put(day, dayMeals);
        }

        // 填充实际数据
        setDishesList.forEach(sd -> {
            DishesVO dishesVO = dishesService.getDishesVoById(sd.getDishesId());
            if (dishesVO != null) {
                mealPlans.get(sd.getWeekDay())
                        .get(sd.getMealTime())
                        .add(dishesVO);
            }
        });

        // 4. 封装返回数据
        CateringSetDetailVO detailVO = new CateringSetDetailVO();
        detailVO.setId(cateringSet.getId());
        detailVO.setName(cateringSet.getName());
        detailVO.setMonthPrice(cateringSet.getMonthPrice());
        detailVO.setMealPlans(mealPlans);

        return Result.success(detailVO);
    }

    @Override
    public Result deleteCateringSet(Long setId) {
        elderFunc.checkCatering(setId);
        CateringSet cateringSet = new CateringSet();
        cateringSet.setId(setId);
        cateringSet.setDelFlag(YesNoEnum.YES.getCode());
        cateringSetMapper.updateById(cateringSet);
        return Result.success();
    }

    @Override
    public Result getSetMealPlan(Long setId) {
        CateringSet cateringSet = cateringSetMapper.selectById(setId);
        AssertUtil.notNull(cateringSet, ExceptionEnum.DATA_NOT_EXIST);

        Map<Integer, Map<Integer, List<DishesVO>>> mealPlans = new HashMap<>();
        for (int day = 1; day <= 7; day++) {
            Map<Integer, List<DishesVO>> dayMeals = new HashMap<>();
            for (int meal = 1; meal <= 3; meal++) {
                dayMeals.put(meal, new ArrayList<>());
            }
            mealPlans.put(day, dayMeals);
        }

        List<SetDishes> setDishesList = setDishesMapper.selectList(
                new QueryWrapper<SetDishes>().eq("set_id", setId)
        );

        setDishesList.forEach(sd -> {
            Dishes dishes = dishesMapper.selectById(sd.getDishesId());
            if (dishes != null && "N".equals(dishes.getDelFlag())) {
                DishesVO dishesVO = BeanUtil.toBean(dishes, DishesVO.class);
                mealPlans.get(sd.getWeekDay())
                        .get(sd.getMealTime())
                        .add(dishesVO);
            }
        });

        CateringSetDetailVO detailVO = BeanUtil.toBean(cateringSet, CateringSetDetailVO.class);
        detailVO.setMealPlans(mealPlans);
        return Result.success(detailVO);
    }

    @Override
    @Transactional
    public Result saveMealPlan(OperateCateringSetQuery query) {
        CateringSet cateringSet = cateringSetMapper.selectById(query.getId());
        AssertUtil.notNull(cateringSet, ExceptionEnum.DATA_NOT_EXIST);

        setDishesMapper.delete(new QueryWrapper<SetDishes>()
                .eq("set_id", query.getId())
        );

        if (query.getMealPlans() != null && !query.getMealPlans().isEmpty()) {
            List<SetDishes> setDishesList = new ArrayList<>();

            query.getMealPlans().forEach((weekDay, mealMap) -> {
                mealMap.forEach((mealTime, dishesIds) -> {
                    dishesIds.forEach(dishesId -> {
                        SetDishes sd = new SetDishes();
                        sd.setSetId(query.getId());
                        sd.setDishesId(dishesId);
                        sd.setWeekDay(weekDay);
                        sd.setMealTime(mealTime);
                        sd.setCreateId(query.getCreateId());
                        sd.setCreateTime(new Date());
                        sd.setUpdateId(query.getUpdateId());
                        sd.setUpdateTime(new Date());
                        setDishesList.add(sd);
                    });
                });
            });

            if (!setDishesList.isEmpty()) {
                setDishesFunc.saveBatchSetDishes(setDishesList);
            }
        }
        return Result.success();
    }

    @Override
    public CateringSetDetailVO getCateringSetDetail(Long setId) {
        // 1. 查询套餐基本信息
        CateringSet cateringSet = cateringSetMapper.selectById(setId);
        AssertUtil.notNull(cateringSet, ExceptionEnum.DATA_NOT_EXIST);

        // 2. 查询套餐菜品关系
        List<SetDishes> setDishesList = setDishesMapper.selectList(
                new LambdaQueryWrapper<SetDishes>().eq(SetDishes::getSetId, setId)
        );

        // 3. 初始化7天3餐结构
        Map<Integer, Map<Integer, List<DishesVO>>> mealPlans = new HashMap<>();
        for (int day = 1; day <= 7; day++) {
            Map<Integer, List<DishesVO>> dayMeals = new HashMap<>();
            for (int meal = 1; meal <= 3; meal++) {
                dayMeals.put(meal, new ArrayList<>());
            }
            mealPlans.put(day, dayMeals);
        }

        // 4. 填充菜品数据
        setDishesList.forEach(sd -> {
            DishesVO dishesVO = dishesService.getDishesVoById(sd.getDishesId());
            if (dishesVO != null) {
                mealPlans.get(sd.getWeekDay())
                        .get(sd.getMealTime())
                        .add(dishesVO);
            }
        });

        // 5. 封装返回数据
        CateringSetDetailVO detailVO = new CateringSetDetailVO();
        detailVO.setId(cateringSet.getId());
        detailVO.setName(cateringSet.getName());
        detailVO.setMonthPrice(cateringSet.getMonthPrice());
        detailVO.setMealPlans(mealPlans);

        return detailVO;
    }
}